<?php

namespace Xin\Logger;

use Psr\Log\LoggerInterface;
use Xin\Logger\Contracts\EnableTimePrint;

class StdoutLogger implements LoggerInterface, EnableTimePrint
{
    use EnableTimePrintable;

    /**
     * @var string
     */
    protected $name;

    /**
     * @param string $name
     */
    public function __construct(string $name)
    {
        $this->name = $name;
    }

    /**
     * @inheritDoc
     */
    public function emergency($message, array $context = []): void
    {
        $this->log('emergency', $message, $context);
    }

    /**
     * @inheritDoc
     */
    public function alert($message, array $context = []): void
    {
        $this->log('alert', $message, $context);
    }

    /**
     * @inheritDoc
     */
    public function critical($message, array $context = []): void
    {
        $this->log('critical', $message, $context);
    }

    /**
     * @inheritDoc
     */
    public function error($message, array $context = []): void
    {
        $this->log('error', $message, $context);
    }

    /**
     * @inheritDoc
     */
    public function warning($message, array $context = []): void
    {
        $this->log('warning', $message, $context);
    }

    /**
     * @inheritDoc
     */
    public function notice($message, array $context = []): void
    {
        $this->log('notice', $message, $context);
    }

    /**
     * @inheritDoc
     */
    public function info($message, array $context = []): void
    {
        $this->log('info', $message, $context);
    }

    /**
     * @inheritDoc
     */
    public function debug($message, array $context = []): void
    {
        $this->log('debug', $message, $context);
    }

    /**
     * @inheritDoc
     */
    public function log($level, $message, array $context = []): void
    {
        $context = $context ?: '';
        $mark = strtoupper("$this->name.$level");
        if ($level === 'info') {
            Printer::info("[$mark]", $this->getTimePrefix() . $message, $context);
        } elseif ($level === 'warning') {
            Printer::warn("[$mark]", $this->getTimePrefix() . $message, $context);
        } elseif (in_array($level, ['emergency', 'alert', 'critical', 'error'])) {
            Printer::error("[$mark]", $this->getTimePrefix() . $message, $context);
        } else {
            Printer::println("[$mark]", $this->getTimePrefix() . $message, $context);
        }
    }
}
